package snoghert.db.util.impl;

import static snoghert.db.util.impl.PersistenceUtilType.DERBY;
import static snoghert.db.util.impl.PersistenceUtilType.DINAMICY_DERBY;

import java.util.HashMap;
import java.util.Map;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

import org.apache.derby.jdbc.EmbeddedDataSource;
import org.apache.naming.java.javaURLContextFactory;

import snoghert.db.util.PersistenceUtil;
import br.com.statizo.financeiro.domain.entity.Entidade;
import br.com.statizo.financeiro.domain.repo.Repositorio;

public class SnoghertPersistenceUtil implements PersistenceUtil{

	private EntityManagerFactory entityManagerFactory;
	private PersistenceUtilType type;
	private String url;

	public SnoghertPersistenceUtil(PersistenceUtilType type) {
		this.type = type;
		initialize();
	}

	public SnoghertPersistenceUtil(String url) {
		this.type = DINAMICY_DERBY;
		this.url = url;
		initialize();
	}

	private void initialize(){
		if(type == PersistenceUtilType.MYSQL){
			entityManagerFactory = Persistence.createEntityManagerFactory(type.getPersistenceUnit());
		}else if(type == PersistenceUtilType.DERBY){
			try {
				initializeDerbyContext();
				entityManagerFactory = Persistence.createEntityManagerFactory(type.getPersistenceUnit());	
			} catch (NamingException e) {
				e.printStackTrace();
			}
		}else if(type == DINAMICY_DERBY){
			Map<String,String> props = new HashMap<String,String>();
			props.put("hibernate.show_sql", "true");
			props.put("hibernate.format_sql", "true");
			props.put("hibernate.dialect", "org.hibernate.dialect.DerbyDialect");
			props.put("hibernate.hbm2ddl.auto", "update");
			props.put("javax.persistence.jdbc.url", "jdbc:derby:" + url + ";create=true");

			entityManagerFactory = Persistence.createEntityManagerFactory(type.getPersistenceUnit(), props);
		}else{
			throw new IllegalArgumentException(String.valueOf(type));
		}
	}

	protected void initializeDerbyContext() throws NamingException{
		System.setProperty(Context.INITIAL_CONTEXT_FACTORY, javaURLContextFactory.class.getName());
		System.setProperty(Context.URL_PKG_PREFIXES, "org.apache.naming");
		InitialContext ic = new InitialContext();
		ic.createSubcontext("java:");
		ic.createSubcontext("java:statizo");
		ic.createSubcontext("java:statizo/env");
		ic.createSubcontext("java:statizo/env/jdbc");
		EmbeddedDataSource ds = new EmbeddedDataSource();
		ds.setDatabaseName("statizodb");
		ds.setCreateDatabase("create");
		ic.bind("java:statizo/env/jdbc/statizoDS", ds);

	}

	public void refreshEntityManager(Repositorio<? extends Entidade> repo) {
		repo.setEntityManager(this.entityManagerFactory.createEntityManager());
	}


	public void close() throws NamingException{
		if(DERBY.equals(this.type)){
			InitialContext ic = new InitialContext();
			ic.unbind("java:statizo/env/jdbc/statizoDS");
		}
		entityManagerFactory.close();
	}

}